import { NextRequest, NextResponse } from 'next/server'
import { getServerSession } from 'next-auth'
import { authOptions } from '@/lib/auth'
import prisma from '@/lib/prisma'

interface StageContent {
  question?: string;
  options?: { id: string; text: string }[];
  correctAnswer?: string | string[];
  maxScore?: number;
  instructions?: string;
  answerExplanation?: string;
  language?: string;
  languageVersion?: string;
  prompt?: string;
  template?: string;
  testCases?: any[];
  allowedFileTypes?: string;
  maxFileSizeMB?: number;
  correctAnswerId?: string | null;
  standardAnswers?: string[];
  matchCase?: boolean;
  points?: number;
  explanationVisibleToStudent?: boolean;
}

export async function GET(
  req: NextRequest,
  { params }: { params: { id: string; stageId: string } }
) {
  const session = await getServerSession(authOptions)

  if (!session?.user?.id) {
    return NextResponse.json({ error: 'Not authenticated' }, { status: 401 });
  }

  const { id: experimentId, stageId } = params;
  const studentId = session.user.id; // Get studentId from session

  if (!experimentId || !stageId) {
    return NextResponse.json({ error: 'Experiment ID and Stage ID are required' }, { status: 400 });
  }

  try {
    const stage = await prisma.experimentStage.findUnique({
      where: { id: stageId },
      include: {
        experiment: {
          select: {
            title: true,
            startTime: true,
            endTime: true,
            allowLateSubmission: true,
            stages: {
              select: { id: true, order: true, title: true },
              orderBy: { order: 'asc' },
            },
          },
        },
      },
    });

    if (!stage) {
      return NextResponse.json({ error: 'Experiment stage not found' }, { status: 404 });
    }
    if (stage.experimentId !== experimentId) {
      return NextResponse.json({ error: 'Stage does not belong to this experiment' }, { status: 400 });
    }
    
    if (session.user.role === 'STUDENT') {
        const now = new Date();
        if (stage.experiment.startTime && now < new Date(stage.experiment.startTime)) {
            return NextResponse.json({ error: 'Experiment has not started yet.' }, { status: 403 });
        }
    }

    let experimentSubmission = await prisma.experimentSubmission.findFirst({
      where: { studentId, experimentId },
    });

    if (!experimentSubmission && session.user.role === 'STUDENT') {
        experimentSubmission = await prisma.experimentSubmission.create({
          data: { studentId, experimentId, status: 'IN_PROGRESS', draftStageAnswers: JSON.stringify({}) }, 
        });
    }
    
    const isStudent = session.user.role === 'STUDENT';
    let canViewExplanation = false;

    // Logic for student unable to submit if experiment ended (already present, seems okay)
    if (isStudent && experimentSubmission) { // Check if experimentSubmission exists for student
        if (stage.experiment.endTime && new Date() > new Date(stage.experiment.endTime) && !stage.experiment.allowLateSubmission) {
            // If experiment is truly over for submission, they might be able to see explanations if opened
        } else if (experimentSubmission.status !== 'GRADED' && experimentSubmission.status !== 'SUBMITTED'){
           // If still in progress for draft, they cannot submit if time is up.
            // This specific check might need to be here for active work, but explanation visibility is separate.
        }
    }

    let draftStageAnswerData = null;
    let stageContentForStudent: StageContent = {};
    if (stage.content && typeof stage.content === 'string') {
      try {
        stageContentForStudent = { ...JSON.parse(stage.content) };
      } catch (e) {
        console.error('Failed to parse stage content JSON:', e);
        stageContentForStudent = {};
      }
    } else if (
      stage.content &&
      typeof stage.content === 'object' &&
      !Array.isArray(stage.content) &&
      stage.content !== null &&
      Object.getPrototypeOf(stage.content) === Object.prototype
    ) {
      stageContentForStudent = { ...(stage.content as Record<string, any>) };
    } else {
      stageContentForStudent = {};
    }

    if (isStudent) {
        // Check if student has any formal submission for this experiment
        const hasSubmittedFormalSnapshot = await prisma.submission.count({
            where: {
                userId: studentId,
                experimentId: experimentId,
            }
        }) > 0;
        
        const experimentEndTime = stage.experiment.endTime ? new Date(stage.experiment.endTime) : null;
        const isExperimentConcluded = experimentEndTime ? new Date() > experimentEndTime : false;

        // Conditions for student to view explanation:
        // 1. The explanation is marked as visible.
        // 2. EITHER the student has made at least one formal submission OR the experiment has concluded.
        if (stageContentForStudent.explanationVisibleToStudent === true && (hasSubmittedFormalSnapshot || isExperimentConcluded)) {
            canViewExplanation = true;
        } 
        
        if (!canViewExplanation && stageContentForStudent.hasOwnProperty('answerExplanation')) {
            delete stageContentForStudent['answerExplanation']; // Remove if not visible or not permitted yet
        }
        // Also remove correct answers if explanation is not visible (or based on other rules)
        if (!canViewExplanation && stageContentForStudent.hasOwnProperty('correctAnswerId')) {
            delete stageContentForStudent['correctAnswerId'];
        }
        if (!canViewExplanation && stageContentForStudent.hasOwnProperty('standardAnswers')) {
            delete stageContentForStudent['standardAnswers'];
        }
    }
    // For teachers/admins, they always see the full content including explanations and correct answers.

    if (experimentSubmission?.draftStageAnswers) {
      try {
        const draftsObject = JSON.parse(experimentSubmission.draftStageAnswers);
        if (draftsObject[stageId]) {
          draftStageAnswerData = {
            id: stageId, 
            answer: draftsObject[stageId].answer,
            score: null, 
            submittedAt: draftsObject[stageId].lastSaved, 
          };
        }
      } catch (parseError) {
        console.error("Failed to parse draftStageAnswers in GET stage details, returning no draft for this stage:", parseError);
      }
    }
    
    const finalStageData = { ...stage, content: stageContentForStudent }; // Use potentially modified content

    return NextResponse.json({
      stage: finalStageData,
      submission: draftStageAnswerData, 
      experimentSubmissionStatus: experimentSubmission?.status 
    });

  } catch (error) {
    console.error('Error fetching stage details for student:', error);
    return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
  }
} 